﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Jobs;

public class Villager : BaseContent
{
    public bool demanding = false;
    public bool demandFulfilled = false;
    public ESupplyType currentDemandType;
    public int currentDemandRemainTime;
    public int currentDemandMaxTime;
    public int nextDemandInterval;

    public int otakuLevel = 0;

    public GameObject requirementBubble;
    public Vector3 floatingTextPos;
    public FloatingText bindFloatingText;
    public Sprite infantSprite;
    public GameObject fxPivot;


    public string[,] quotes = new string[,]
    {
        {"人生最要不得的，就是饥肠辘辘和形单影只。", "陌生人，你终将拥有一个答案，只需顺其自然。", "挣扎是违背承诺、粉碎梦想的地狱。","时间不逝，圆环不圆。"},
        { "快乐总是千篇一律，但快却不是。快！快！", "享受这个世界的荒谬吧。这会减少很多痛苦。", "人生苦短，无梦难活。","你终将成为我。"},
        { "孩子们不该被逼着上床睡觉……", "我好快乐，但好吃力……", "仿生人会梦见电子羊吗……", "我想爱、想吃、也想变成天空上半明半暗的云。"}
        


    };
    // Start is called before the first frame update
    void Start()
    {
        GameManager.Instance.BindToOnMove(OnMove);
        nextDemandInterval = Random.Range(1, GameManager.GetData().InitialDemandDelay+1);
        bindFloatingText = FloatingTextManager.SpawnText(transform.position + floatingTextPos);
        ClearQuote();
    }

    // Update is called once per frame
    void Update()
    {
        

    }
    public void OnMove()
    {
        // On Player Moved
        demandFulfilled = false;
        ClearQuote();
        if (demanding)
        {
            currentDemandRemainTime -= 1;
            if (currentDemandRemainTime <= 0)
            {
                OnDemandExpired();
            }
        }
        else if (otakuLevel < GameManager.GetData().GetOtakuLevelMax())
        {
            nextDemandInterval -= 1;
            if (nextDemandInterval <= 0)
            {
                GenerateDemand();
            }
        }

        
    }

    void ClearQuote()
    {
        bindFloatingText.SetText("");
    }
    void SetQuote()
    {
        int i = Random.Range(0, 4);
        string q = quotes[otakuLevel,i];
        bindFloatingText.SetText(q);
    }

    void GenerateDemand()
    {
        currentDemandType = GetPreferedDemandType();
        currentDemandMaxTime = (int)GameManager.GetData().GetOtakuLevelConfig(otakuLevel).MaxDemandTolerance;
        currentDemandRemainTime = currentDemandMaxTime;
        demanding = true;
        demandFulfilled = false;
        requirementBubble.SetActive(true);
        SetQuote();
    }

    ESupplyType GetPreferedDemandType()
    {
        int d_a = GetNearestSupplyStationOfType(ESupplyType.Love);
        int d_b = GetNearestSupplyStationOfType(ESupplyType.Game);
        int d_c = GetNearestSupplyStationOfType(ESupplyType.Food);

        d_a = d_a > 0 ? d_a : 100;
        d_b = d_b > 0 ? d_b : 100;
        d_c = d_c > 0 ? d_c : 100;

        float c_a = Mathf.Pow(d_a, GetProbabilityFalloffFromOtakuLevel());
        float c_b = Mathf.Pow(d_b, GetProbabilityFalloffFromOtakuLevel());
        float c_c = Mathf.Pow(d_c, GetProbabilityFalloffFromOtakuLevel());

        float choice = Random.Range(0f, c_a + c_b + c_c);
        Debug.Log("c_a=" + c_a.ToString() + ";c_b=" + c_b.ToString() + ";c_c=" + c_c.ToString() + ";choice=" + choice.ToString());
        if (choice < c_a)
        {
            Debug.Log("result = a");
            return ESupplyType.Love;
        }
        else if (choice < c_a + c_b)
        {
            Debug.Log("result = b");
            return ESupplyType.Game;
        }
        else if (choice < c_a + c_b + c_c)
        {
            Debug.Log("result = c");
            return ESupplyType.Food;
        }
        return ESupplyType.Love;
    }

    float GetProbabilityFalloffFromOtakuLevel()
    {
        return GameManager.GetData().GetOtakuLevelConfig(otakuLevel).ProbabilityFalloff;
    }

    public void OnDemandExpired()
    {
        demanding = false;
        currentDemandRemainTime = 0;
        currentDemandMaxTime = 0;
        nextDemandInterval = GetDemandInterval();
        
        if (otakuLevel >= 1)
        {
            otakuLevel = otakuLevel - 1;
            FXManager.PlayFX("ZhaiDown", fxPivot.transform);
        }

        SetQuote();
    }

    public void OnDemandFulfilled()
    {
        Debug.Log("Demand Fulfilled");
        demanding = false;
        demandFulfilled = true;
        currentDemandRemainTime = 0;
        currentDemandMaxTime = 0;
        nextDemandInterval = GetDemandInterval();

        IncrementOtakuLevel();

        SetQuote();
        GameManager.Instance.OnDeliver();
    }

    public void IncrementOtakuLevel()
    {
        if (otakuLevel < GameManager.GetData().GetOtakuLevelMax())
        {
            otakuLevel = otakuLevel + 1;
            if (otakuLevel == GameManager.GetData().GetOtakuLevelMax())
            {
                PolyMorph();

            }
        }
        FXManager.PlayFX("ZhaiUp", fxPivot.transform);

    }

    public void PolyMorph()
    {
        FXManager.PlayFX("PolyMorph", transform);

        SpriteRenderer spr = GetComponent<SpriteRenderer>();
        spr.sprite = infantSprite;
    }

    int GetDemandInterval()
    {
        return Random.Range(GameManager.GetData().GetOtakuLevelConfig(otakuLevel).MinDemandInterval, GameManager.GetData().GetOtakuLevelConfig(otakuLevel).MaxDemandInterval+1);
    }

    public override void OnInteract(PlayerPawn interactor)
    {
        base.OnInteract(interactor);

        if (demanding && interactor.TryFulfillSupply(currentDemandType))
        {
            OnDemandFulfilled();
        }

    }


    public int GetNearestSupplyStationOfType(ESupplyType type)
    {
        int minDistance = 999999;
        SupplyStation result = null;
        List<SupplyStation> candidates = GameManager.Instance.GetContentList<SupplyStation>();
        for (int i = 0; i < candidates.Count; i++)
        {
            
            int tempDistance = candidates[i].rootTile.DistanceTo(rootTile);
            if (candidates[i].supplyType == type && tempDistance < minDistance)
            {
                result = candidates[i];
                minDistance = tempDistance;
            }
        }

        if (result)
        {
            return minDistance;
        }
        else
        {
            return -1;
        }
    }
}
